package com.power.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.power.constant.ManagerContstants;
import com.power.domain.SysRole;
import com.power.domain.SysRoleMenu;
import com.power.domain.SysUserRole;
import com.power.ex.handle.BussinessException;
import com.power.mapper.SysRoleMapper;
import com.power.mapper.SysRoleMenuMapper;
import com.power.mapper.SysUserRoleMapper;
import com.power.service.SysRoleMenuService;
import com.power.service.SysRoleService;
import com.power.util.AuthUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dingchunlin
 * @description 针对表【sys_role(角色)】的数据库操作Service实现
 * @createDate 2024-07-10 15:12:14
 */
@Service
@CacheConfig(cacheNames = "com.power.service.impl.SysRoleServiceImpl")
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 查询角色列表
     *
     * @return
     */
    @Override
    @Cacheable(key = ManagerContstants.SYS_ALL_ROLE_KEY)
    public List<SysRole> queryRoleList() {
        return sysRoleMapper.selectList(new LambdaQueryWrapper<SysRole>()
                .orderByDesc(SysRole::getCreateTime));
    }

    /**
     * 保存角色信息
     *
     * @param sysRole
     * @return
     */
    @Override
    @CacheEvict(key = ManagerContstants.SYS_ALL_ROLE_KEY)
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveSysRole(SysRole sysRole) {
        // 新增角色
        sysRole.setCreateUserId(AuthUtils.getUserId());
        sysRole.setCreateTime(new Date());
        int insert = sysRoleMapper.insert(sysRole);
        if (insert > 0) {
            // 获取角色ID
            Long roleId = sysRole.getRoleId();
            // 获取角色拥有的权限
            List<Long> idList = sysRole.getMenuIdList();
            if (CollectionUtils.isNotEmpty(idList) && idList.size() > 0) {
                List<SysRoleMenu> roleMenuList = new ArrayList<>();
                // 循环遍历权限ID，插入角色权限关系表
                idList.forEach(id -> {
                    SysRoleMenu roleMenu = new SysRoleMenu();
                    roleMenu.setRoleId(roleId);
                    roleMenu.setMenuId(id);
                    roleMenuList.add(roleMenu);
                });
                sysRoleMenuService.saveBatch(roleMenuList);
            }
        }
        return insert > 0;
    }

    /**
     * 根据角色ID查询角色信息
     *
     * @param id 角色ID
     * @return 角色信息
     */
    @Override
    public SysRole querySysRoleInfoByRoleId(Long id) {
        // 查询角色信息
        SysRole sysRole = sysRoleMapper.selectById(id);
        // 查询角色拥有的权限
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, id));
        if (CollectionUtils.isNotEmpty(sysRoleMenuList) && sysRoleMenuList.size() > 0) {
            List<Long> menuIdList = sysRoleMenuList.stream()
                    .map(SysRoleMenu::getMenuId)
                    .collect(Collectors.toList());
            sysRole.setMenuIdList(menuIdList);
        }
        return sysRole;
    }

    /**
     * 修改角色信息
     *
     * @param sysRole 角色信息
     * @return 是否修改成功
     */
    @Override
    @CacheEvict(key = ManagerContstants.SYS_ALL_ROLE_KEY)
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifySysRole(SysRole sysRole) {
        // 获取角色id
        Long roleId = sysRole.getRoleId();
        // 删除角色拥有的权限
        sysRoleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId));
        // 获取角色拥有的权限
        List<Long> idList = sysRole.getMenuIdList();
        if (CollectionUtils.isNotEmpty(idList) && idList.size() > 0) {
            List<SysRoleMenu> roleMenuList = new ArrayList<>();
            // 循环遍历权限ID，插入角色权限关系表
            idList.forEach(id -> {
                SysRoleMenu roleMenu = new SysRoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(id);
                roleMenuList.add(roleMenu);
            });
            sysRoleMenuService.saveBatch(roleMenuList);
        }
        // 修改角色信息
        int update = sysRoleMapper.updateById(sysRole);
        return update > 0;
    }

    /**
     * 根据角色ID删除角色信息
     * @param roleIdList 角色ID列表
     * @return 是否删除成功
     */
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(key = ManagerContstants.SYS_ALL_ROLE_KEY)
    @Override
    public Boolean removeSysRoleByIds(List<Long> roleIdList) {
        // 首先判断角色id是否有角色在使用
        Long count = sysUserRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>()
                .in(SysUserRole::getRoleId, roleIdList));
        if (count > 0) {
            throw new BussinessException("该角色已被用户使用，不能删除");
        }
        // 批量或单个删除角色权限信息
        sysRoleMenuMapper.delete( new LambdaQueryWrapper<SysRoleMenu>()
                .in(SysRoleMenu::getRoleId, roleIdList));
        // 批量删除角色信息
        return sysRoleMapper.deleteBatchIds(roleIdList) == roleIdList.size();
    }
}




